import TextureInfo from "./comps/TextureInfo";
import SDKManager from "../sdk/SDKManager";

/**
 * https://github.com/cocos-creator/example-cases/tree/master/assets/cases/07_capture_texture
 * auth 游子陈 20200625
 * RenderTexture 辅助类
 */
export default class TextureRenderUtils {




    //截屏使用的的摄像机
    protected camera: cc.Camera = null;
    //截屏取的节点
    protected renderNode: cc.Node = null;
    //需要使用canvas创建图片时使用的。
    protected _canvas: any = null;
    //取屏幕像素点颜色使用。
    protected texture: cc.RenderTexture;

    getTexture() {
        return this.texture;
    }

    getPixelFormat() {
        return this.texture.getPixelFormat()
    }


    get width() {
        return this.texture.width
    }

    get height() {
        return this.texture.height
    }


    init(camera: cc.Camera, renderNode: cc.Node, formart?) {
        this.camera = camera;
        this.renderNode = renderNode;
        let texture = new cc.RenderTexture();
        if (!formart) {
            formart = cc['gfx'].RB_FMT_S8
        }
        // cc.log('renderNode ', renderNode, ' renderNode.height ', renderNode.height, ' renderNode.width ', renderNode.width)
        // cc.log(' camera group ',this.camera.node.group)
        // cc.log(' renderNode group ',this.renderNode.group)
        texture.initWithSize(Math.floor(renderNode.width), Math.floor(renderNode.height), formart);
        this.camera.targetTexture = texture;
        this.texture = texture;
    }


    createCanvas(): void {
        let width = this.texture.width;
        let height = this.texture.height;
        if (!this._canvas) {
            this._canvas = SDKManager.getChannel().createCanvas()
            this._canvas.width = width;
            this._canvas.height = height;
        }
        else {
            this.clearCanvas();
        }

    }


    render(node?) {
        this.camera.render(node ? node : this.renderNode);
    }

    getCanvas(): any {
        return this._canvas;
    }

    stopCamera() {
        this.camera.node.active = false;
    }


    /**
     * 获取截取的图片
     */
    getSpriteFrame() {
        let spriteFrame = new cc.SpriteFrame();
        spriteFrame.setTexture(this.texture);
        return spriteFrame;
    }

    getSprite() {
        let spriteFrame = new cc.SpriteFrame();
        spriteFrame.setTexture(this.texture);
        let node = new cc.Node();
        let sprite = node.addComponent(cc.Sprite);
        sprite.spriteFrame = spriteFrame;
        return node;
    }

    readPixels(data: Uint8Array, x: number, y: number, w: number, h: number) {
        return this.texture.readPixels(data, x, y, w, h)
    }

    getData(): any {
        let data: ArrayBufferView = this.texture.readPixels();
        if (!data) {
            cc.error(' getDate error ', data)
            return null;
        }
        // cc.log(' data .length ', data.length)
        return data;
    }

    /**
     * 获得一个node所对应的所有数据
     * node 需要色湖之锚点 anchorPoint 0,0
     * readPixel获得的数据时从左下开始的。
     * @param node 
     */
    getDataByNode(node: cc.Node) {
        let pos = node.convertToWorldSpaceAR(cc.v2(0, 0))
        let x = pos.x
        let y = pos.y
        let width = Math.floor(node.width)
        let height = Math.floor(node.height)
        x = Math.floor(x)
        y = Math.floor(y)
        let data = this.getData();
        let dataList = []
        let startY = y;
        let rowBytes = width * 4;
        let rowW = Math.floor(this.width) * 4//一行的长度
        for (let row = 0; row < height; row++) {
            let srow = startY + row;//行开始位置
            let startX = srow * rowW + x * 4;//列开始位置
            for (let i = 0; i < rowBytes; i++) {
                dataList.push(data[startX + i]);
            }

        }
        return dataList;
    }

    getDataUrl() {
        this.render()
        this.createCanvas()
        this.updateCanvase();
        let data = this.toDataURL();
        return data;
    }
    toDataURL() {
        return this._canvas.toDataURL();
    }

    getTextureInfo() {
        // let tex = new TextureInfo(this.width, this.height, this.getData(), this.getPixelFormat())
        return TextureInfo.createByTexture(this.texture);
    }

    updateCanvase(): any {
        let width = this.texture.width;
        let height = this.texture.height;
        let ctx = this._canvas.getContext('2d');
        let data = this.texture.readPixels();
        // write the render data
        let rowBytes = width * 4;
        for (let row = 0; row < height; row++) {
            let srow = height - 1 - row;
            let imageData = ctx.createImageData(width, 1);
            let start = srow * width * 4;
            for (let i = 0; i < rowBytes; i++) {
                imageData.data[i] = data[start + i];
            }
            ctx.putImageData(imageData, 0, row);
        }
    }

    static getTexture(img): cc.Texture2D {
        let texture = new cc.Texture2D();
        texture.initWithElement(img);
        return texture;
    }

    static getSpriteFrameByTextureInfo(info: TextureInfo) {
        let texture = new cc.Texture2D()
        texture.initWithData(info.data, info.fomart, info.width, info.height)
        let sf = new cc.SpriteFrame(texture)
        return sf;
    }

    static getSpriteFrameByDataUrl(dataUrl, callback: Function) {
        this.createImg(dataUrl, (img) => {
            let texture = this.getTexture(img)
            let spriteFrame = this.getSpriteFrame(texture)
            callback(spriteFrame)
        })

        // return spriteFrame;
    }




    static getSpriteFrame(texture) {

        let spriteFrame = new cc.SpriteFrame();
        spriteFrame.setTexture(texture);
        return spriteFrame
    }

    static createImg(dataURL, callback: Function) {
        var img = document.createElement("img");
        img.onload = function () {
            callback(img)
        }
        img.onerror = function(){
        }
        img.src = dataURL;
        // return img;
    }

    clearCanvas() {
        let ctx = this._canvas.getContext('2d');
        ctx.clearRect(0, 0, this._canvas.width, this._canvas.height);
    }


    static showImage(img) {
        let texture = new cc.Texture2D();
        texture.initWithElement(img);

        let spriteFrame = new cc.SpriteFrame();
        spriteFrame.setTexture(texture);

        let node = new cc.Node();
        let sprite = node.addComponent(cc.Sprite);
        sprite.spriteFrame = spriteFrame;

        node.zIndex = cc.macro.MAX_ZINDEX;
        node.parent = cc.director.getScene();
        // set position
        let width = cc.winSize.width;
        let height = cc.winSize.height;
        node.x = width / 2;
        node.y = height / 2;
        node.on(cc.Node.EventType.TOUCH_START, () => {
            node.parent = null;
            node.destroy();
        });

        this.captureAction(node, width, height);
    }

    static captureAction(capture, width, height) {
        let scaleAction = cc.scaleTo(1, 0.3);
        let targetPos = cc.v2(width - width / 6, height / 4);
        let moveAction = cc.moveTo(1, targetPos);
        let spawn = cc.spawn(scaleAction, moveAction);
        capture.runAction(moveAction);

    }
}
